#include "utils_string_ex.h"
#include <array>
#include <execinfo.h>
#include <sstream>
#include <sys/time.h>
#include <cxxabi.h>
#include <dlfcn.h>
#include <string>
#include <random>

namespace El {
namespace Utils {

std::string utc32ToString(uint32_t utc)
{
    std::time_t timestamp = utc;
    std::tm timeinfo;
    // 使用localtime_r将UTC时间转换为本地时间
    localtime_r(&timestamp, &timeinfo);
    char buffer[80];
    std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &timeinfo);
    return std::string(buffer);
}

std::string utc64ToString(uint64_t utc)
{
    // 将微秒转换为秒和微秒
    std::time_t seconds = utc / 1000000;
    long long microseconds = utc % 1000000;

    std::tm timeinfo;
    // 使用localtime_r将秒转换为本地时间
    localtime_r(&seconds, &timeinfo);

    char buffer[100]; // 增加缓冲区大小以容纳微秒
    // 先格式化日期和时间部分
    size_t len = std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &timeinfo);

    // 追加微秒部分
    snprintf(buffer + len, sizeof(buffer) - len, ".%06lld", microseconds);

    return std::string(buffer);
}

std::string utcToString(std::chrono::system_clock::time_point tp)
{
    // 将 time_point 转换为微秒再调用 uint64_t 版本
    return utc64ToString(std::chrono::duration_cast<std::chrono::microseconds>(tp.time_since_epoch()).count());
}

const std::string ALPHANUMERIC_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
std::string GenerateToken(size_t length)
{
    std::random_device rd;
    std::mt19937 generator(rd());
    std::uniform_int_distribution<> distribution(0, ALPHANUMERIC_CHARS.size() - 1);

    std::string token;
    token.reserve(length);
    for (size_t i = 0; i < length; ++i) {
        token += ALPHANUMERIC_CHARS[distribution(generator)];
    }
    return token;
}

void Split(const std::string &input, const std::string &delimiter, std::vector<std::string> &result)
{
    if (input.empty()) {
        return;
    }

    size_t start = 0;
    size_t end = input.find(delimiter);
    while (end != std::string::npos) {
        std::string substring = input.substr(start, end - start);
        if (!substring.empty()) {
            result.push_back(substring);
        }
        start = end + delimiter.length();
        end = input.find(delimiter, start);
    }
    std::string lastSubstring = input.substr(start, end);
    if (!lastSubstring.empty()) {
        result.push_back(lastSubstring);
    }
}

} // namespace Utils
} // namespace El